iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
自我挑戰組

學JS的心路歷程系列 第 22

#學JS的心路歷程 Day22-物件與原型(一)

  • 分享至 

  • xImage
  •  

前兩天說明物件導向的三大特性及 JS 不符合物件導向,只能稱作支援物件導向而已,今天我們來看看 JS 的原型繼承。
首先我們先來看,什麼是原型:

兩個物件之間的原型關係 (prototype relationship) 跟繼承 (inheritance) 有關:
每個物件都可以有另一個物件作為它的原型 (prototype) , 如此一來,前者就會繼承其原型的所有特性。
一個物件藉由內部特性 (property) [[Prototype]] 來指定其原型。
每個物件都有這個特性,但它可能是 null 。由 [[Prototype]] 連接起來的物件串鏈 (chain of objects) 被稱作 原型串鏈 (prototype chain)
《Speaking JavaScript 第十七章-物件與繼承》

我相信第一次看到這段話的人肯定是滿臉問號,我也是一樣。

沒關係我們一步一步慢慢來看!

簡單來說,可以定義一些自動成為可讓其它物件存取的屬性和功能

在 JS 中,我們可以很容易的建立一個物件,也可以輕易的修改和刪除已經指派給物件的屬性。

var obj = {
    a : 'apple',
    b : function(){},
    c : {},
    d : []
};
obj.a = [];
obj.b = "banana";
delete obj.c;

在開發過程中,我們都會盡量避免重複造輪子,也就是盡可能的重複利用現有的程式碼。

所以一種可重複利用的程式碼,並幫助我們把程式組織好的方式就是「繼承」,把存在於某個物件上的功能延伸到其他物件上。

在 JS 中,繼承就是用「原型」實作出來的。

透過原型,物件可以存取屬於其他物件的屬性

const Jason = {
    CSS : true
};
const Turtle = {
    JS : true
};
const Kai = {
    Vue : true
};

我們剛剛建立了三個物件,每個物件都有一個自己才能存取的屬性。

可以利用 in 測試物件能否存取某個屬性:

"JS" in Jason;//false
"CSS" in Jason;//true

如果我們想要 Json 存取 TurtleJS 屬性,可以用 Object.setPrototypeOf ,需要兩個引數 (argument) ,並把第二個引數設為第一個引數的原型,所以我們可以這樣做:

Object.setPrototypeOf(Jason,Turtle);
"JS" in Jason;//true

現在我們可以透過 Jason 存取 JS 屬性了,這是因為每當像 Jason 存取 JS 時,便會在物件原型裡搜尋該屬性,因為我們已經讓 Jason繼承了 Turtle 讓它成為其原型,所以可以存取 Turtle 的屬性。

在 JS 中,物件原型是物件的內部屬性,無法直接存取,所以會標示為 [[Prototype]]

那如果我們想要 Jason 也能存取 Kai 的屬性,相信很多人會直接這樣寫:

Object.setPrototypeOf(Jason,Kai);
"JS" in Jason;//false
"Vue" in Jason;//true

Jason 的確可以存取 Kai 的屬性了,但同時 Kai 也取代了 Turtle 成為了它的原型。

那我們該怎麼做呢?我們前面有提到過「每個物件都有 [[Prototype]] 特性可以來來指定其原型。」,所以 Turtle 成為 Jason 原型後,也可以指定 Kai 當作其原型,這個行為稱為「原型串鏈 (prototype chain) 」。

Object.setPrototypeOf(Jason,Turtle);
Object.setPrototypeOf(Turtle,Kai);
"JS" in Jason;//true
"Vue" in Jason;//true

可以看到說 Jason 已經可以順利存取 TurtleKai 的屬性了!

那麼,今天就到這邊,一樣如果有錯誤及來源未附上也歡迎留言指正,那麼我們明天見。

參考資料 :
忍者 JavaScript 開發技巧探秘
Speaking JavaScript


上一篇
學JS的心路歷程 Day21-JS 支援物件導向?(二)
下一篇
學JS的心路歷程 Day23 -物件與原型(二)
系列文
學JS的心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Gary
iT邦新手 5 級 ‧ 2023-08-22 16:31:32

參考資料沒放到連結喔

我要留言

立即登入留言